﻿using PipeServer.Enum;
using PipeServer.Model;
using RpcHelper;
using SocketBuffer;

namespace PipeServer
{
    internal class PipeHelper
    {
        public const int HeadLen = 9;
        private const byte _PageVer = 253;
        /// <summary>
        /// 读取数据包
        /// </summary>
        /// <param name="data"></param>
        internal static void ReadPage(object data)
        {
            Model.GetDataPage arg = (Model.GetDataPage)data;
            arg.Allot.InitInfo(arg);
            object resData = arg.Allot.Action();
            if ((PageType.单向 & arg.PageType) != PageType.单向 && resData != null)
            {
                Page page = Page.GetReplyPage(arg, resData);
                if (!arg.Client.Send(page, out string error))
                {
                    new LogInfo(error, LogGrade.ERROR, "Socket_Server")
                    {
                        LogTitle = "服务端回复事件包错误!",
                        LogContent = page.ToJson()
                    }.Save();
                }
            }
        }
        private static int _InitHeadBody(ISocketBuffer buffer, DataPage page)
        {
            int index = 9;
            if (page.DataLen <= short.MaxValue)
            {
                index += buffer.WriteShort((short)page.DataLen, index);

            }
            else
            {
                index += buffer.WriteLong(page.DataLen, index);
            }
            index += buffer.WriteByte(Tools.CSByByte(buffer.Stream, index), index);
            index += buffer.WriteChar(page.Type, index);
            return index;
        }

        /// <summary>
        /// 获取包头信息
        /// </summary>
        /// <param name="pageId"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        private static void _InitPageHead(ISocketBuffer buffer, DataPage page)
        {
            buffer.WriteByte(_PageVer, 0);
            buffer.WriteByte((byte)page.PageType, 1);
            buffer.WriteByte((byte)page.DataType, 2);
            buffer.WriteByte(page.HeadType, 3);
            buffer.WriteLong(page.DataId, 4);
            buffer.WriteByte((byte)page.Type.Length, 8);
            if (page.DataLen != 0)
            {
                int len = _InitHeadBody(buffer, page);
                buffer.Write(page.Content, len);
            }
            else
            {
                buffer.WriteByte(Tools.CSByByte(buffer.Stream, 9), 9);
                buffer.WriteChar(page.Type, 10);
            }
        }
        /// <summary>
        /// 获取发送的字节流
        /// </summary>
        /// <param name="pageInfo"></param>
        /// <returns></returns>
        internal static ISocketBuffer GetSendBuffer(DataPage page)
        {
            ISocketBuffer buffer = BufferCollect.ApplySendBuffer(page.GetPageSize(), page.DataId);
            _InitPageHead(buffer, page);
            return buffer;
        }



        /// <summary>
        /// 组建数据包
        /// </summary>
        /// <param name="data"></param>
        /// <param name="num"></param>
        /// <param name="objPage"></param>
        internal static bool SplitPage(byte[] data, int size, ref Model.DataPageInfo objPage, Client.PipeClient client)
        {
            int index = 0;
            return PipeHelper.SplitPage(data, size, ref index, ref objPage, client);
        }
        internal static bool SplitPage(byte[] data, int size, ref int index, ref Model.DataPageInfo objPage, Client.PipeClient client)
        {
            if (objPage == null)
            {
                if (data[index] != _PageVer)
                {
                    return false;
                }
                objPage = new Model.DataPageInfo();
            }
            if (objPage.LoadData(data, size, ref index))
            {
                client.ReceiveComplate();
                if (size > index)
                {
                    return PipeHelper.SplitPage(data, size, ref index, ref objPage, client);
                }
                return true;
            }
            return objPage.LoadProgress != PageLoadProgress.包校验错误;
        }

    }
}
